#include <regx52.h>
#include "key.h"
#include "seg.h"
#include <intrins.h>

typedef unsigned char u8;
/* 变量声明区 */
//数码管相关变量
unsigned short Seg_slow = 0;//数码管减速变量
u8 Seg_buf[6] = {10,10,10,10,10,10};//数码管显示内容数组
u8 Seg_pos = 0;//数码管索引
u8 Seg_disp_mode = 0;//数码管显示模式
u8 Seg_led_set_flag = 0;//数码管显示led设置界面，0-运行模式 1-运行速度
u8 Seg_star_flag = 0;//数码管闪烁变量
u8 date_disp_fag = 0;//0表示运行模式，1表示长按状态
u8 led_date = 0;//记录led亮的灯
//led相关变量
u8 led_mode = 0;//led显示模式变量
unsigned short led_speed[4] = {400,500,600,700};//led流转速度
u8 led_disp_mode =  0xfe;
u8 led_disp_mode3_4[4] = {0x7e,0xbd,0xdb,0xe7};
u8 led_disp_mode3_4_index = 0;
unsigned short led_speed_set[4] = {400,400,400,400};
u8 speed_set_index = 0;
//按键相关变量
unsigned char Key_val,Key_down,Key_up,Key_old;
unsigned char Key_slow;//按键减速

//定时器计数变量
unsigned short timer_led_speed = 0;//用于led延时
u8 flag = 0;//系统暂停标志位
unsigned short star_timer_400ms = 0;//闪烁计时

/* 按键数据处理 */
void Key_proces()
{
	u8 i = 0;//循环变量
	if(Key_slow)return;
	Key_slow = 1;
	
	Key_val = Key_read();
	Key_down = Key_val & (Key_val ^ Key_old);
	Key_up = ~Key_val & (Key_val ^ Key_old);
	Key_old = Key_val;
	if(flag == 0)
	{
		if(Key_old == 4&&Seg_disp_mode == 0)
			date_disp_fag = 1;
		else
			date_disp_fag = 0;
	}
	else
		date_disp_fag = 0;
	switch(Key_down)
	{
		case 1:
		{
			if(Seg_disp_mode == 0)
			{
				flag ^= 1;	
			}			
			break;
		}
		case 2:
		{
			if(Seg_disp_mode == 0)//如果在模式1下按下，则是第一次按下
			{
				flag = 0;//暂停led流水灯
				Seg_disp_mode = 1;//数码管显示模式 切换到模式2
				for(i = 0; i < 4;i++)
				{
					led_speed_set[i] = led_speed[i];//将流转界面的值赋给设置界面
				}
			}
			else
			{				
				Seg_led_set_flag ^= 1;//设置运行模式与流转速度切换
				if(Seg_led_set_flag == 0)//第二此切换，则跳转到运行模式，并保存设置
				{
					for(i = 0;i < 4;i++)
					{
						led_speed[i] = led_speed_set[i];//保存设置
						Seg_disp_mode = 0;//转换到数码管模式1
						flag = 1;//开启流水灯
					}
				}
			}
			break;
		}
		case 3:
		{
			if(Seg_disp_mode == 1)
			{
				if(Seg_led_set_flag == 0)
				{
					if(++speed_set_index == 4)speed_set_index = 0;						
				}
				else if(Seg_led_set_flag == 1)
				{					
					led_speed_set[speed_set_index] += 100;
					if(led_speed_set[speed_set_index] > 1200)
						led_speed_set[speed_set_index] = 400;
				}
			}
			
			break;
		}
		case 4:
		{
			if(Seg_disp_mode == 1)
			{
				if(Seg_led_set_flag == 0)
				{
					if(--speed_set_index == 255)speed_set_index = 3;						
				}
				else if(Seg_led_set_flag == 1)
				{					
					led_speed_set[speed_set_index] -= 100;
					if(led_speed_set[speed_set_index] < 400)
						led_speed_set[speed_set_index] = 1200;
				}
			}
			break;
		}
	}
}


/* 数码管信息处理函数 */
void Seg_proces()
{
	unsigned char i = 0;//用于熄灭高位数码管
	if(Seg_slow)return;
	Seg_slow = 1;
	while((~led_disp_mode & (0x01 << i)) != (0x01 << i))
		i++;
	if(led_mode < 2)
		led_date = i + 1;
	else
		led_date = (i + 1)*10 + (8 - i);
	switch(Seg_disp_mode)
	{
		case 0:
		{
			if(date_disp_fag == 0)
			{
				if(flag)
					Seg_buf[0] = 11;//地位数码管显示R有点像A
				else
					Seg_buf[0] = 5;
				Seg_buf[1] = led_mode + 1;
				Seg_buf[2] = led_speed[led_mode] / 1000;
				Seg_buf[3] = led_speed[led_mode] /100 %10;
				Seg_buf[4] = led_speed[led_mode] /10 % 10;
				Seg_buf[5] = led_speed[led_mode] %10;
				if(Seg_buf[2] == 0)
				{
					Seg_buf[2] = 10;
				}
			}
			else
			{
				Seg_buf[0] = 0;
				Seg_buf[1] = 5;
				Seg_buf[2] = 12;
				Seg_buf[3] = led_mode + 1;
				Seg_buf[4] = led_date /10;
				Seg_buf[5] = led_date %10;
			}
		
			break;
		}
		case 1:
		{
			Seg_buf[0] = 12;
			Seg_buf[1] = speed_set_index + 1;
			Seg_buf[2] = led_speed_set[speed_set_index] / 1000;
			Seg_buf[3] = led_speed_set[speed_set_index] /100 %10;
			Seg_buf[4] = led_speed_set[speed_set_index] /10 % 10;
			Seg_buf[5] = led_speed_set[speed_set_index] %10;
			if(Seg_led_set_flag == 0)
			{
				Seg_buf[0] = Seg_star_flag?12 : 10;
				Seg_buf[1] = Seg_star_flag?speed_set_index + 1 : 10;	
			}
			else
			{
				Seg_buf[2] = Seg_star_flag?(led_speed_set[speed_set_index] / 1000) : 10;
				Seg_buf[3] = Seg_star_flag?(led_speed_set[speed_set_index] /100 %10) : 10;
				Seg_buf[4] = Seg_star_flag?(led_speed_set[speed_set_index] /10 % 10) : 10;
				Seg_buf[5] = Seg_star_flag?(led_speed_set[speed_set_index] %10) : 10;
			}				
			if(Seg_buf[2] == 0)
			{
				Seg_buf[2] = 10;
			}
			break;
		}
	}
}
/* led处理函数 */
void led_peoces()
{
	P1 = led_disp_mode;
	if(timer_led_speed == led_speed[led_mode])
	{
		timer_led_speed = 0;
		switch(led_mode)
		{
			case 0:
			{
				if(led_disp_mode == 0x7e)
					led_disp_mode = 0xfe;
				else
				{
					led_disp_mode = _crol_(led_disp_mode,1);
					if(led_disp_mode == 0x7f)led_mode = 1;
				}
				
				break;
			}
			case 1:
			{
				led_disp_mode = _cror_(led_disp_mode,1);
				if(led_disp_mode == 0xfe)led_mode = 2;
				break;
			}
			case 2:
			{
				led_disp_mode = led_disp_mode3_4[led_disp_mode3_4_index];
				if(++led_disp_mode3_4_index == 4)
				{
					led_mode = 3;
					led_disp_mode3_4_index = 3;
				}
				break;
			}
			case 3:
			{
				led_disp_mode = led_disp_mode3_4[led_disp_mode3_4_index];
				if(--led_disp_mode3_4_index == 255)
				{
					led_mode = 0;
					led_disp_mode3_4_index = 0;
				}
				break;
			}
		}
	}  
}

/* 定时器初始化函数 */
void Timer0Init(void)		//1毫秒@12.000MHz
{
	TMOD &= 0xF0;		//设置定时器模式
	TMOD |= 0x01;		//设置定时器模式
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	TF0 = 0;		//清除TF0标志
	TR0 = 1;		//定时器0开始计时
	ET0 = 1;
	EA = 1;
}


/* 定时器0中断服务函数 */
void timer0server() interrupt 1
{
	TL0 = 0x18;		//设置定时初值
	TH0 = 0xFC;		//设置定时初值
	if(++Seg_slow == 500)Seg_slow = 0;
	if(flag)
		timer_led_speed++;
	if(++Key_slow == 10)Key_slow = 0;
	if(++Seg_pos == 6)Seg_pos = 0;
	if(++star_timer_400ms == 400)
	{
		star_timer_400ms = 0;
		Seg_star_flag ^= 1;
	}
	Seg_disp(Seg_pos,Seg_buf[Seg_pos],0);
}

/* 主函数 */
void main()
{
	Timer0Init();
	while(1)
	{
		Key_proces();
		Seg_proces();
		led_peoces();
	}
}